package com.erik.crawler.task;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import com.erik.crawler.model.IpInfo;
import com.erik.crawler.service.ehcache.ProxyEhcache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
@ConfigurationProperties
public class ProxyValidTask {

    private static Logger LOGGER = LoggerFactory.getLogger(ProxyValidTask.class);
    private ExecutorService workerGroup = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);

    @Autowired
    private ProxyEhcache proxyEhcache;

    @Value("${task.valid.enabled}")
    private Boolean enabled;

    /**
     * The validity of timing verification agent
     */
    @Scheduled(initialDelay = 10 * 1000, fixedDelay = 2 * 60 * 1000)
    public void validProxyScheduled() {

        if (enabled) {//on-off
            long count = this.proxyEhcache.count();
            LOGGER.info("===>>>There are [{}] proxy left in the current proxy pool", count);

            Map<String, IpInfo> ipInfoMap = this.proxyEhcache.batchQuery();
            if (!CollectionUtils.isEmpty(ipInfoMap)) {
                Iterator<Map.Entry<String, IpInfo>> entries = ipInfoMap.entrySet().iterator();

                while (entries.hasNext()) {
                    Map.Entry<String, IpInfo> entry = entries.next();
                    workerGroup.submit(() -> {
                        LOGGER.info(entry.getValue().toString());
                        String ip = entry.getValue().getIpStr();
                        int port = Integer.parseInt(entry.getValue().getPort());

                        try {
                            HttpRequest request = new HttpRequest("http://httpbin.org/get");
                            Proxy httpProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ip, port));
                            request.setProxy(httpProxy);
                            HttpResponse response = request.timeout(5000).executeAsync();

                            if (response.getStatus() == HttpStatus.HTTP_OK) {
                                this.proxyEhcache.validOk(ip);
                            } else {
                                this.proxyEhcache.decrementOrRemove(ip);
                            }
                        } catch (Exception e) {
                            LOGGER.warn("===>>>Proxy [{}] validation failed", ip);
                            this.proxyEhcache.decrementOrRemove(ip);
                        }
                    });
                }

            }

        }
    }
}
